package org.csu.mall.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.csu.mall.common.CONSTANT;
import org.csu.mall.common.ResponseCode;
import org.csu.mall.common.UniformResponse;
import org.csu.mall.entity.*;
import org.csu.mall.persistence.CartMapper;
import org.csu.mall.persistence.CommodityMapper;
import org.csu.mall.persistence.CorderMapper;
import org.csu.mall.persistence.MerchantOrderMapper;
import org.csu.mall.service.ICartService;
import org.csu.mall.util.CodeUtil;
import org.csu.mall.util.DateUtil;
import org.csu.mall.util.PropertiesUtil;
import org.csu.mall.vo.CartCommodityListVO;
import org.csu.mall.vo.CartCommodityVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Service("cartService")
public class ICartServiceImpl implements ICartService {

    @Autowired
    private CartMapper cartMapper;

    @Autowired
    private CommodityMapper commodityMapper;

    @Autowired
    private MerchantOrderMapper merchantOrderMapper;

    @Autowired
    private CorderMapper corderMapper;

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public UniformResponse<String> addCart(String itemId, Integer quantity, Account account) {
        if(account == null){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.USER_NOT_LOGIN.getCode(), ResponseCode.USER_NOT_LOGIN.getDescription());
        }
        if(StringUtils.isBlank(itemId)){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.ILLEGAL_ARGUMENT.getCode(), ResponseCode.ILLEGAL_ARGUMENT.getDescription());
        }
        Commodity commodity = commodityMapper.selectOne(Wrappers.<Commodity>query().eq("item_id", itemId));
        Cart cart = new Cart();
        cart.setUserId(account.getUserId());
        cart.setItemId(commodity.getItemId());
        cart.setItemName(commodity.getItemName());
        cart.setQuantity(quantity);
        cart.setChecked(CONSTANT.CartCommodityStatus.CHECKED.getCode());
        cart.setCreateTime(LocalDateTime.now());
        cart.setUpdateTime(LocalDateTime.now());
        int row = cartMapper.insert(cart);
        if(row > 0){
            return UniformResponse.createForSuccessMessage(ResponseCode.SUCCESS.getDescription());
        }
        return UniformResponse.createForErrorCodeMessage(ResponseCode.ERROR.getCode(), ResponseCode.ERROR.getDescription());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public UniformResponse<String> removeCart(Integer id, Account account) {
        if(account == null){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.USER_NOT_LOGIN.getCode(), ResponseCode.USER_NOT_LOGIN.getDescription());
        }
        if(id == null){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.ILLEGAL_ARGUMENT.getCode(), ResponseCode.ILLEGAL_ARGUMENT.getDescription());
        }
        int row = cartMapper.deleteById(id);
        if(row > 0){
            return UniformResponse.createForSuccessMessage(ResponseCode.SUCCESS.getDescription());
        }
        return UniformResponse.createForErrorCodeMessage(ResponseCode.ERROR.getCode(), ResponseCode.ERROR.getDescription());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public UniformResponse<String> addQuantity(Integer id, Integer quantity, Account account) {
        if(account == null){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.USER_NOT_LOGIN.getCode(), ResponseCode.USER_NOT_LOGIN.getDescription());
        }
        if(quantity == null){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.ILLEGAL_ARGUMENT.getCode(), ResponseCode.ILLEGAL_ARGUMENT.getDescription());
        }
        Cart cart = cartMapper.selectById(id);
        cart.setQuantity(quantity);
        cart.setUpdateTime(LocalDateTime.now());
        int row= cartMapper.updateById(cart);
        if(row > 0){
            return UniformResponse.createForSuccessMessage(ResponseCode.SUCCESS.getDescription());
        }
        return UniformResponse.createForErrorCodeMessage(ResponseCode.ERROR.getCode(), ResponseCode.ERROR.getDescription());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public UniformResponse<CartCommodityListVO> lookCart(Account account, int pageSize, int pageNum) {
        if(account == null){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.USER_NOT_LOGIN.getCode(), ResponseCode.USER_NOT_LOGIN.getDescription());
        }

        Page<Cart> result = new Page<>();
        result.setCurrent(pageNum);
        result.setSize(pageSize);

        QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", account.getUserId());

        result = cartMapper.selectPage(result,queryWrapper);
        CartCommodityListVO cartCommodityListVO = this.pageToVO(result);
        return UniformResponse.createForSuccess(
                ResponseCode.SUCCESS.getDescription(), cartCommodityListVO);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public UniformResponse<CartCommodityVO> cartPurchase(Integer id, Account account) {
        if(account == null){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.USER_NOT_LOGIN.getCode(), ResponseCode.USER_NOT_LOGIN.getDescription());
        }
        Cart cartItem = cartMapper.selectById(id);
        CartCommodityVO cartCommodityVO = this.entityToVO(cartItem);
        UniformResponse response = this.removeCart(id, account);
        if(!response.isSuccess()){
            return response;
        }
        return UniformResponse.createForSuccess(ResponseCode.SUCCESS.getDescription(), cartCommodityVO);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public UniformResponse<String> updateChecked(Integer id, Integer checked, Account account) {
        if(account == null){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.USER_NOT_LOGIN.getCode(), ResponseCode.USER_NOT_LOGIN.getDescription());
        }
        Cart cartItem = new Cart();
        cartItem.setId(id);
        if(CONSTANT.CartCommodityStatus.CHECKED.getCode() == checked){
            cartItem.setChecked(CONSTANT.CartCommodityStatus.CHECKED.getCode());
        }
        if(CONSTANT.CartCommodityStatus.UNCHECKED.getCode() == checked){
            cartItem.setChecked(CONSTANT.CartCommodityStatus.UNCHECKED.getCode());
        }
        int row = cartMapper.updateById(cartItem);
        if(row > 0){
            return UniformResponse.createForSuccessMessage(ResponseCode.SUCCESS.getDescription());
        }
        return UniformResponse.createForErrorCodeMessage(
                ResponseCode.ERROR.getCode(), ResponseCode.ERROR.getDescription());
    }


    @Override
    public UniformResponse<Map<String, String>> purchaseCheckedCommodity(Account account) {
        if(account == null){
            return UniformResponse.createForErrorCodeMessage(
                    ResponseCode.USER_NOT_LOGIN.getCode(), ResponseCode.USER_NOT_LOGIN.getDescription());
        }
        List<Cart> cartList = cartMapper.selectList(
                Wrappers.<Cart>query().eq("checked", CONSTANT.CartCommodityStatus.CHECKED).eq("user_id", account.getUserId()));
        //未成功下单的商品信息
        Map<String, String> map = Maps.newHashMap();
        //收货地址
        String address = account.getAddress().split(";")[0];

        for(Cart cart : cartList){
            MerchantOrder merchantOrder = merchantOrderMapper.selectOne(
                    Wrappers.<MerchantOrder>query().eq("item_id", cart.getItemId()));
            Commodity commodity = commodityMapper.selectOne(
                    Wrappers.<Commodity>query().eq("item_id", cart.getItemId()));
            CustomerOrder customerOrder = new CustomerOrder();
            if(merchantOrder == null || commodity == null){
                map.put(cart.getItemId(), ResponseCode.COMMODITY_NOT_EXIST.getDescription());
                continue;
            }
            //设置购买数量
            if(cart.getQuantity() <= commodity.getStock()){
                customerOrder.setItemNumber(cart.getQuantity());
            }else {
                customerOrder.setItemNumber(commodity.getStock());
            }
            customerOrder.setOrderName(cart.getItemName());
            customerOrder.setItemId(cart.getItemId());
            customerOrder.setItemName(cart.getItemName());
            customerOrder.setUnitPrice(commodity.getPrice());
            customerOrder.setTotalPrice(commodity.getPrice() * cart.getQuantity());
            customerOrder.setOrderSource(commodity.getSource());
            customerOrder.setUserId(account.getUserId());
            customerOrder.setMerchantId(merchantOrder.getMerchantId());
            customerOrder.setOrderState(CONSTANT.CustomerOrderStatus.UNPAID.getCode());
            customerOrder.setCPhone(account.getPhoneNumber());
            customerOrder.setMPhone(merchantOrder.getPhoneNumber());
            customerOrder.setCAddress(address);
            customerOrder.setMAddress(merchantOrder.getAddress());
            customerOrder.setCreateTime(LocalDateTime.now());
            customerOrder.setUpdateTime(LocalDateTime.now());
            customerOrder.setOrderId(CodeUtil.createOrderId());
            int row = corderMapper.insert(customerOrder);
            if(row == 0){
                map.put(cart.getItemId(), ResponseCode.ERROR.getDescription());
                continue;
            }
            cartMapper.deleteById(cart.getId());
            map.put(cart.getItemId(), ResponseCode.SUCCESS.getDescription());
        }

        return UniformResponse.createForSuccess(ResponseCode.SUCCESS.getDescription(), map);
    }

    private CartCommodityVO entityToVO(Cart cart){
        Commodity commodity = commodityMapper.selectOne(
                Wrappers.<Commodity>query().eq("item_id", cart.getItemId()));
        if(commodity == null){
            return null;
        }
        CartCommodityVO cartCommodityVO = new CartCommodityVO();
        cartCommodityVO.setId(cart.getId());
        cartCommodityVO.setItemId(cart.getItemId());
        cartCommodityVO.setItemName(cart.getItemName());
        //设置购买数量
        int buyLimitCount = 0;
        if(commodity.getStock() >= cart.getQuantity()){
            buyLimitCount = cart.getQuantity();
            cartCommodityVO.setLimitQuantity(CONSTANT.Cart.LIMIT_NUM_SUCCESS);
        }else{
            buyLimitCount = commodity.getStock();
            cartCommodityVO.setLimitQuantity(CONSTANT.Cart.LIMIT_NUM_FAILURE);

            Cart cartForQuantity = new Cart();
            cartForQuantity.setId(cart.getId());
            cartForQuantity.setQuantity(buyLimitCount);
            int rows = cartMapper.updateById(cartForQuantity);
        }
        cartCommodityVO.setQuantity(buyLimitCount);
        cartCommodityVO.setChecked(cart.getChecked());

        //新增
        cartCommodityVO.setSource(commodity.getSource());
        cartCommodityVO.setPrice(commodity.getPrice());
        cartCommodityVO.setTotalPrice(commodity.getPrice() * cart.getQuantity());
        cartCommodityVO.setStatus(commodity.getStatus());
        cartCommodityVO.setImage(commodity.getImage());
        cartCommodityVO.setStar(commodity.getStar());
        cartCommodityVO.setCreateTime((DateUtil.localDateTimeToString(commodity.getCreateTime())));
        cartCommodityVO.setUpdateTime(DateUtil.localDateTimeToString(commodity.getUpdateTime()));
        cartCommodityVO.setImageHost(PropertiesUtil.getProperty("image.server.url"));
        return cartCommodityVO;
    }

    private CartCommodityListVO pageToVO(Page<Cart> result){
        CartCommodityListVO cartCommodityListVO = new CartCommodityListVO();
        cartCommodityListVO.setPageNum(result.getCurrent());
        cartCommodityListVO.setPageSize(result.getSize());
        cartCommodityListVO.setStartRow(1);
        cartCommodityListVO.setEndRow(result.getPages());
        cartCommodityListVO.setTotal(result.getTotal());
        cartCommodityListVO.setPages(result.getPages());
        List<Cart> cartList = result.getRecords();
        List<CartCommodityVO> cartCommodityVOList = Lists.newArrayList();

        Double allPrice = 0.00;
        for(Cart cart: cartList){
            CartCommodityVO cartCommodityVO = this.entityToVO(cart);
            cartCommodityVOList.add(cartCommodityVO);
            if(cart.getChecked() == CONSTANT.CartCommodityStatus.CHECKED.getCode()){
                allPrice += cartCommodityVO.getTotalPrice();
            }
        }
        cartCommodityListVO.setAllPrice(allPrice);
        cartCommodityListVO.setImageHost(PropertiesUtil.getProperty("image.server.url"));

        cartCommodityListVO.setCartCommodityVOList(cartCommodityVOList);
        cartCommodityListVO.setFirstPage(1l);
        cartCommodityListVO.setPrePage(result.getCurrent() - 1);
        cartCommodityListVO.setNextPage(result.getCurrent() + 1);
        cartCommodityListVO.setIsFirstPage(result.getCurrent() == 1);
        cartCommodityListVO.setIsLastPage(result.getCurrent() == result.getPages());
        cartCommodityListVO.setHasPreviousPage(result.getCurrent() > 1);
        cartCommodityListVO.setHasNextPage(result.getCurrent() < result.getPages());
        return cartCommodityListVO;
    }
}
